package sprs;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.rosuda.REngine.Rserve.RConnection;

public class RConnectionPool {

	private static int count = 0;
	private static RPool rPool;

	public final static boolean isWin = System.getProperty("os.name").toUpperCase().indexOf("WIN") >= 0;

	public static synchronized RPool<RConnection> getPool() {
		if (rPool == null) {

			GenericObjectPoolConfig gopc = new GenericObjectPoolConfig();
			gopc.setMaxTotal(40);
			gopc.setMinIdle(5);
			Factory f = new Factory();
			rPool = new RPool(f, gopc);

		}
		return rPool;

	}

	public static class Factory extends BasePooledObjectFactory<RConnection> {

		@Override
		public RConnection create() throws Exception {

			// count++;
			// System.out.println("count=" + count);

			RConnection rc;
			if (isWin)
				rc = new RConnection("ulpd326.madc.att.com");
			else
				rc = new RConnection("localhost");
			rc.voidEval("library(compiler)");
			rc.voidEval("enableJIT(3)");
			rc.voidEval("library(forecast)");
			return rc;
		}

		@Override
		public PooledObject<RConnection> wrap(RConnection r) {
			return new DefaultPooledObject<RConnection>(r);
		}

		@Override
		public void passivateObject(PooledObject<RConnection> parser) throws Exception {
			// parser.getObject().reset();
		}

		@Override
		public boolean validateObject(PooledObject<RConnection> parser) {
			// return parser.getObject().isValid();
			return true;
		}

		@Override
		public void destroyObject(PooledObject<RConnection> parser) {
			// return parser.getObject().isValid();
			parser.getObject().close();
		}

	}

	public static class RPool<RConnection> extends GenericObjectPool<RConnection> {

		/**
		 * Constructor.
		 * 
		 * It uses the default configuration for pool provided by
		 * apache-commons-pool2.
		 * 
		 * @param factory
		 */
		public RPool(PooledObjectFactory<RConnection> factory) {
			super(factory);
		}

		/**
		 * Constructor.
		 * 
		 * This can be used to have full control over the pool using
		 * configuration object.
		 * 
		 * @param factory
		 * @param config
		 */
		public RPool(PooledObjectFactory<RConnection> factory, GenericObjectPoolConfig config) {
			super(factory, config);
		}

	}

}
